package cn.exrick.xboot.base.serviceimpl

import cn.exrick.xboot.base.entity.Area
import cn.exrick.xboot.base.entity.DepartmentUser
import cn.exrick.xboot.base.entity.SupervisionUser
import cn.exrick.xboot.base.mapper.AreaMapper
import cn.exrick.xboot.base.service.IAreaService
import cn.exrick.xboot.base.service.IDepartmentUserService
import cn.exrick.xboot.base.service.IEnterpriseUserService
import cn.exrick.xboot.base.service.ISupervisionUserService
import cn.exrick.xboot.core.common.constant.CommonConstant
import cn.exrick.xboot.core.common.utils.ResultUtil
import cn.exrick.xboot.core.common.utils.SecurityUtil
import cn.exrick.xboot.core.common.utils.ToolUtil
import cn.exrick.xboot.core.common.vo.Result
import cn.exrick.xboot.core.service.mybatis.IUserRoleService
import com.baomidou.mybatisplus.core.toolkit.Wrappers
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import lombok.extern.slf4j.Slf4j
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import reactor.core.publisher.Flux
import reactor.core.scheduler.Schedulers
import java.util.*
import javax.annotation.Resource

/**
 * 区域管理接口实现
 * @author Fei
 */
@Slf4j
@Service
@Transactional
open class IAreaServiceImpl : ServiceImpl<AreaMapper?, Area?>(), IAreaService {

    @Resource
    private val securityUtil: SecurityUtil? = null

    @Autowired
    private var iSupervisionUserService: ISupervisionUserService? = null

    @Autowired
    private var iUserRoleService: IUserRoleService? = null

    @Autowired
    private lateinit var iDepartmentUserService: IDepartmentUserService

    override fun insertArea(area: Area?): Result<Any>? {

       return area?.run {

            if (parentId.isNullOrEmpty()) parentId = CommonConstant.PARENT_ID
            parentTitle = getById(parentId)?.run { title }
            save(this)
            areaLevel = getAreaLevel(id)
            updateById(this)

            getById(parentId)?.let {

                it.isParent = true
                updateById(it)
            }

            return@run ResultUtil.success("新增成功！")
        }
    }

    override fun getAreaByAreaLevel(): Result<MutableList<Area?>>? {


        val areaWrapper = KtQueryWrapper(Area::class.java).orderByDesc(Area::createTime)

        if (!iUserRoleService!!.findByUserId(securityUtil!!.currUser.id)?.map { it.id }?.contains("496138616573952")!!)
            areaWrapper.eq(Area::areaLevel, iDepartmentUserService.getOne(KtQueryWrapper(DepartmentUser::class.java)
                    .eq(DepartmentUser::userId, securityUtil.currUser.id))?.userLevel)
        else
            areaWrapper.eq(Area::parentId, CommonConstant.PARENT_ID)

       return ToolUtil.setListToNul(list(areaWrapper))?.run {

            ResultUtil.data(this, "获取区域列表数据成功")
        } ?: ResultUtil.error(201,"暂无数据")
    }

    private fun getAreaLevel(id: String): Int? {

       return getById(id)?.run {

            if (parentId!! == CommonConstant.PARENT_ID) {

                return@run 1

            } else if (getById(parentId!!)?.let { it.parentId!! == CommonConstant.PARENT_ID } !!) {

                return@run 2
            } else {

                return@run 3
            }
        }
    }

    override fun deleteArea(areaIds: Array<out String>): Result<Any> {

        return try {

            removeByIds(areaIds.toList())
            ResultUtil.success("移除成功！")
        }catch (e: Exception) {

            ResultUtil.error("移除失败")
        }
    }

    override fun updateArea(area: Area?): Result<Any>? {

       return area?.run {

            updateById(area)
            ResultUtil.success<Any>("编辑成功！")
        } ?: ResultUtil.error("编辑失败")
    }

    override fun getByPid(areaId: String?): Result<MutableList<Area?>>? {

        val pid = if (ToolUtil.isEmpty(areaId)) CommonConstant.PARENT_ID else areaId!!

        return ToolUtil.setListToNul(list(KtQueryWrapper(Area::class.java).eq(Area::parentId, pid).orderByAsc(Area::createTime)))?.let {

            ResultUtil.data(it)
        }
    }

    override fun getAreaById(id: String?): Result<Area>? {

        return getById(id)?.let { ResultUtil.data(it, "获取详情成功") }
    }

    override fun getAreaFullNameByAreaId(areaId: String?): String? {

        return buildAreaName(areaId)
    }

    private fun buildAreaName(areaId: String?): String? {

       return getById(areaId)?.run {

           getById(parentId)?.let {

               it.title.plus("/").plus(title)
           } ?: title
       }
    }
}